# -*- coding;utf-8 -*-
"""
File name : myViewSet.PY
Program IDE : PyCharm
Create file time: 2022/4/3 18:25
File Create By Author : 朱清闯
"""
from rest_framework import viewsets
from rest_framework.response import Response
from rest_framework import status
from rest_framework import filters as rest_filter
from utils.response_result import error_result
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework.permissions import IsAuthenticated, IsAdminUser
from utils.Mypermission import IsOwnerPermission
from django.db.models import Q
from utils.FlatQuestion import flat_question, flat_retriever_questions
from utils.MyCustomResponse import CustomResponse
from utils.MyPage import SmallPage
from question.serializers import QuestionSerializer, QuestionDeserializer



class BaseViewSet(viewsets.ModelViewSet):
    filter_backends = (
        DjangoFilterBackend,
        rest_filter.SearchFilter,
        rest_filter.OrderingFilter,
    )


class MyModelViewSet(viewsets.ModelViewSet):
    def create(self, request, *args, **kwargs):
        partial = kwargs.pop('partial', False)
        instance = self.get_object()
        serializer = self.get_serializer(instance, data=request.data, partial=partial)
        is_valid = serializer.is_valid(raise_exception=False)
        if not is_valid:
            return Response({'code': 0, 'msg': '失败', 'data': serializer.errors})
        self.perform_update(serializer)
        if getattr(instance, '_prefetched_objects_cache', None):
            instance._prefetched_objects_cache = {}
        return Response({'code': 200, 'msg': '成功', 'data': serializer.data})


class CustomNoQuestionsModelViewSet(BaseViewSet):

    def create(self, request, *args, **kwargs):
        response = super().create(request, *args, **kwargs)
        return Response(error_result(code=200, results=response.data))

    def retrieve(self, request, *args, **kwargs):
        response = super().retrieve(request, *args, **kwargs)
        data = response.data
        return Response(error_result(code=200, results=data))

    def update(self, request, *args, **kwargs):
        response = super().update(request, *args, **kwargs)
        return Response(error_result(code=200, results=response.data['results']))

    def list(self, request, *args, **kwargs):
        response = super().list(request, *args, **kwargs)
        data = response.data['results']
        return Response(error_result(code=200, results=data, total=len(response.data['results'])))

    def destroy(self, request, *args, **kwargs):
        response = super().destroy(request, *args, **kwargs)
        return Response(error_result(code=200, results=response.data))


class CustomModelViewSet(viewsets.ModelViewSet):
    filter_backends = (
        DjangoFilterBackend,
        rest_filter.SearchFilter,
        rest_filter.OrderingFilter,
    )

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return CustomResponse(data=serializer.data, code=201, msg="OK", status=status.HTTP_201_CREATED, headers=headers)

    def retrieve(self, request, *args, **kwargs):
        response = super().retrieve(request, *args, **kwargs)
        results = response.data
        current_node = ''
        node_dict = {"questions": "", 'knowledgepoints': 'questions', 'sections': 'knowledgepoints',
                     'chapters': 'sections', 'courses': 'chapters', 'subjects': 'courses'}
        # 寻找该数据父节点所处的位置
        flag = False
        for i in node_dict:
            for key in results:
                if key == i:
                    current_node = i
                    flag = True
                    break
            if flag:
                break

        if not flag:
            return Response(error_result(results=response.data))
        questions_list = []
        results = results[current_node]
        if current_node != "questions":
            current_node = node_dict[current_node]
            for i in results:
                questions_list += flat_retriever_questions(current_node, current_list=i)
        else:
            questions_list += results
        # 以下是去掉重复的题目
        # raw_list_len = len(questions_list)
        # n = len(questions_list)
        # i = 0
        # while i < n:
        #     content = questions_list[i]["content"]
        #     j = i + 1
        #     while j < n:
        #         if content == questions_list[j]["content"]:
        #             questions_list.pop(j)
        #             n -= 1
        #         j += 1
        #     i += 1
        # 读取除results以外的其他数据count,next,previous等,并进行封装
        n = len(questions_list)
        my_response_data = {}
        for key in response.data:
            if key != "results":
                my_response_data[key] = response.data[key]
                if key == 'count':
                    my_response_data[key] = n
        my_response_data["data"] = questions_list
        return Response(error_result(results=my_response_data))

    def update(self, request, *args, **kwargs):
        if "id" in request.data:
            request.data.pop("id")
        if "create_at" in request.data:
            request.data.pop("create_at")
        if "update_at" in request.data:
            request.data.pop("update_at")
        if "is_deleted" in request.data:
            request.data.pop("is_deleted")
        if "create_user" in request.data:
            request.data.pop("create_user")
        partial = kwargs.pop('partial', False)
        instance = self.get_object()
        serializer = self.get_serializer(instance, data=request.data, partial=partial)
        serializer.is_valid(raise_exception=True)
        self.perform_update(serializer)
        if getattr(instance, '_prefetched_objects_cache', None):
            instance._prefetched_objects_cache = {}
        return CustomResponse(data=serializer.data, code=200, msg='OK', status=status.HTTP_200_OK)

    def destroy(self, request, *args, **kwargs):
        instance = self.get_object()
        self.perform_destroy(instance)
        return CustomResponse(data=[], code=204, msg='OK', status=status.HTTP_204_NO_CONTENT)

    def list(self, request, *args, **kwargs):
        response = super().list(request, *args, **kwargs)
        results = response.data["results"]
        if len(results) == 0:
            return Response(error_result(code=1099, msg="no"))
        current_node = ''
        node_dict = ["questions", 'knowledgepoints', 'sections', 'chapters', 'courses']
        # 寻找该数据父节点所处的位置
        flag = False
        for i in node_dict:
            for key in results[0]:
                if key == i:
                    current_node = i
                    flag = True
                    break
            if flag:
                break
        # 如果当前是questions列表，则直接返回
        if not flag:
            return Response(error_result(results=response.data))
        question_list = []
        for i in results:
            question_list += flat_question(current_node, current_list=i)
        # 去掉不在线和不公开的题目
        i = 0
        while i < len(question_list):
            if question_list[i]['open_level'] != 'public' or not question_list[i]['online']:
                question_list.pop(i)
            i += 1
        n = len(question_list)
        # 以下是去掉重复的题目
        # i = 0
        # while i < n:
        #     content = question_list[i]["content"]
        #     j = i + 1
        #     while j < n:
        #         if content == question_list[j]["content"]:
        #             question_list.pop(j)
        #             n -= 1
        #         j += 1
        #     i += 1
        # 读取除results以外的其他数据count,next,previous等,并进行封装

        # 1. 实例化分页器对象
        page_obj = SmallPage()
        # 2. 使用自己配置的分页器调用分页方法进行分页
        page_data = page_obj.paginate_queryset(question_list, request)
        # 3. 序列化我们分页好的数据
        ser_obj = QuestionSerializer(page_data, many=True)
        # 4. 返回数据
        response.data['count'] = n
        response.data["results"] = ser_obj.data
        return Response(error_result(code=200, results=response.data))

